package com.bailian.app.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 连接状态检查工具类
 * 用于检查客户端连接状态，避免向已断开的客户端发送响应
 * 
 * @author bailian
 */
public class ConnectionStatusUtil {
    
    private static final Logger log = LoggerFactory.getLogger(ConnectionStatusUtil.class);
    
    /**
     * 检查客户端连接是否仍然有效
     * 
     * @return true表示连接有效，false表示连接已断开
     */
    public static boolean isClientConnected() {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes == null) {
                return false;
            }
            
            HttpServletRequest request = attributes.getRequest();
            HttpServletResponse response = attributes.getResponse();
            
            if (request == null || response == null) {
                return false;
            }
            
            // 检查请求是否已被中断
            if (request.isAsyncStarted()) {
                try {
                    // 尝试获取异步上下文，如果失败说明连接已断开
                    request.getAsyncContext();
                } catch (Exception e) {
                    if (log.isDebugEnabled()) {
                        log.debug("异步请求上下文获取失败，客户端可能已断开: {}", e.getMessage());
                    }
                    return false;
                }
            }
            
            // 检查响应是否已被提交
            if (response.isCommitted()) {
                return false;
            }
            
            return true;
        } catch (Exception e) {
            if (log.isDebugEnabled()) {
                log.debug("检查客户端连接状态时发生异常: {}", e.getMessage());
            }
            return false;
        }
    }
    
    /**
     * 安全地写入响应，如果客户端断开则忽略
     * 
     * @param responseWriter 响应写入器
     * @return true表示写入成功，false表示客户端已断开
     */
    public static boolean safeWriteResponse(ResponseWriter responseWriter) {
        if (!isClientConnected()) {
            if (log.isDebugEnabled()) {
                log.debug("客户端已断开，跳过响应写入");
            }
            return false;
        }
        
        try {
            responseWriter.write();
            return true;
        } catch (IOException e) {
            if (log.isDebugEnabled()) {
                log.debug("写入响应时发生IO异常，客户端可能已断开: {}", e.getMessage());
            }
            return false;
        } catch (Exception e) {
            log.warn("写入响应时发生异常: {}", e.getMessage());
            return false;
        }
    }
    
    /**
     * 响应写入器接口
     */
    @FunctionalInterface
    public interface ResponseWriter {
        void write() throws IOException;
    }
    
    /**
     * 检查并记录连接状态
     * 
     * @param operation 操作描述
     * @return true表示连接有效
     */
    public static boolean checkConnectionAndLog(String operation) {
        boolean connected = isClientConnected();
        if (!connected && log.isDebugEnabled()) {
            log.debug("执行操作'{}'时检测到客户端已断开", operation);
        }
        return connected;
    }
} 